package com.fqcar.fqdf.ui;

import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.fqcar.fqdf.DFApp;
import com.fqcar.fqdf.R;
import com.fqdf.framework.android.util.CheckLogicUtil;
import com.fqdf.framework.android.util.DialogUtil;

public class MapLocationActivity extends MapWithCacheActivity implements BDLocationListener {

    private DFApp dfApp;

    private MyLocationConfiguration locationConfiguration;

    private final static int TIME_SPAN = 2000;
    // 默认定位间隔时间
    private int updateLocationTime = TIME_SPAN;

    private LocationPositionRunnable locationPositionRunnable;

    private boolean isOpenUserLocation = false;

//    private AMapLocation curValidLocation;

    private BDLocation curValidLocation;


    private MaterialDialog openLocationSettingDialog;

    private float mCurrentDirection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        dfApp = getMyApplication();
    }

    /**
     * 获取定位设置
     *
     * @return 返回定位设置。
     */
    protected MyLocationConfiguration getMyLocationConfig() {
        if (locationConfiguration == null) {
            locationConfiguration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL
                    , true, BitmapDescriptorFactory.fromResource(R.drawable.img_location));
        }
        return locationConfiguration;
    }

    /**
     * 开启定位更新
     *
     * @param time 更新时间间隔
     */
    protected void startLocationUpdate(int time, boolean openUserLocation) {
        updateLocationTime = time;
        isOpenUserLocation = openUserLocation;
        setOpenUserLocation(openUserLocation);
        locationPositionRunnable = new LocationPositionRunnable();
        getUiHandler().post(locationPositionRunnable);
    }

    /**
     * 设置当前用户定位是否开启
     *
     * @param openUserLocation
     */
    protected void setOpenUserLocation(boolean openUserLocation) {
        if (openUserLocation) {
            openCurLocationLayer();
            updateCurLocationLayer(getCurValidLocation());
        } else {
            closeCurLocationLayer();
        }
    }

    /**
     * 开启定位更新
     */
    protected void startLocationUpdate(boolean openUserLocation) {
        startLocationUpdate(TIME_SPAN, openUserLocation);
    }

    /**
     * 开启定位更新，并且不开启
     */
    protected void startLocationUpdate() {
        startLocationUpdate(TIME_SPAN, true);
    }

    /**
     * 关闭定位更新
     */
    protected void closeLocationUpdate() {
        if (locationPositionRunnable != null) {
            getUiHandler().removeCallbacks(locationPositionRunnable);
        }
    }

    @Override
    public void onReceiveLocation(BDLocation location) {
            //获取定位结果
            location.getTime();    //获取定位时间
            location.getLocationID();    //获取定位唯一ID，v7.2版本新增，用于排查定位问题
            location.getLocType();    //获取定位类型
            location.getLatitude();    //获取纬度信息
            location.getLongitude();    //获取经度信息
            location.getRadius();    //获取定位精准度
            location.getAddrStr();    //获取地址信息
            location.getCountry();    //获取国家信息
            location.getCountryCode();    //获取国家码
            location.getCity();    //获取城市信息
            location.getCityCode();    //获取城市码
            location.getDistrict();    //获取区县信息
            location.getStreet();    //获取街道信息
            location.getStreetNumber();    //获取街道码
            location.getLocationDescribe();    //获取当前位置描述信息
            location.getPoiList();    //获取当前位置周边POI信息

            location.getBuildingID();    //室内精准定位下，获取楼宇ID
            location.getBuildingName();    //室内精准定位下，获取楼宇名称
            location.getFloor();    //室内精准定位下，获取当前位置所处的楼层信息

            if (location.getLocType() == BDLocation.TypeGpsLocation){

                //当前为GPS定位结果，可获取以下信息
                location.getSpeed();    //获取当前速度，单位：公里每小时
                location.getSatelliteNumber();    //获取当前卫星数
                location.getAltitude();    //获取海拔高度信息，单位米
                location.getDirection();    //获取方向信息，单位度

                curValidLocation = location;
                locateChange(location);
            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){

                //当前为网络定位结果，可获取以下信息
                location.getOperators();    //获取运营商信息

                curValidLocation = location;
                locateChange(location);

            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {
                curValidLocation = location;
                locateChange(location);
                //当前为网络定位结果

            } else if (location.getLocType() == BDLocation.TypeServerError) {

                //当前网络定位失败
                //可将定位唯一ID、IMEI、定位失败时间反馈至loc-bugs@baidu.com

            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {

                //当前网络不通

            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {

                //当前缺少定位依据，可能是用户没有授权，建议弹出提示框让用户开启权限
                //可进一步参考onLocDiagnosticMessage中的错误返回码

            }
    }

    /**
     * 获取当前定位的位置信息。主要用来初始化以及定位当前数据使用
     */
    private class LocationPositionRunnable implements Runnable {

        @Override
        public void run() {
            BDLocation curLocation = dfApp.getCurLocation();
            if (curLocation != null) {
                new MyLocationListener().onReceiveLocation(curLocation);
            }
            getUiHandler().postDelayed(this, updateLocationTime);
        }
    }
    class MyLocationListener extends BDAbstractLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {

            //获取定位结果
            location.getTime();    //获取定位时间
            location.getLocationID();    //获取定位唯一ID，v7.2版本新增，用于排查定位问题
            location.getLocType();    //获取定位类型
            location.getLatitude();    //获取纬度信息
            location.getLongitude();    //获取经度信息
            location.getRadius();    //获取定位精准度
            location.getAddrStr();    //获取地址信息
            location.getCountry();    //获取国家信息
            location.getCountryCode();    //获取国家码
            location.getCity();    //获取城市信息
            location.getCityCode();    //获取城市码
            location.getDistrict();    //获取区县信息
            location.getStreet();    //获取街道信息
            location.getStreetNumber();    //获取街道码
            location.getLocationDescribe();    //获取当前位置描述信息
            location.getPoiList();    //获取当前位置周边POI信息

            location.getBuildingID();    //室内精准定位下，获取楼宇ID
            location.getBuildingName();    //室内精准定位下，获取楼宇名称
            location.getFloor();    //室内精准定位下，获取当前位置所处的楼层信息

            if (location.getLocType() == BDLocation.TypeGpsLocation){

                //当前为GPS定位结果，可获取以下信息
                location.getSpeed();    //获取当前速度，单位：公里每小时
                location.getSatelliteNumber();    //获取当前卫星数
                location.getAltitude();    //获取海拔高度信息，单位米
                location.getDirection();    //获取方向信息，单位度

                curValidLocation = location;
                locateChange(location);
            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){

                //当前为网络定位结果，可获取以下信息
                location.getOperators();    //获取运营商信息

                curValidLocation = location;
                locateChange(location);

            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {
                curValidLocation = location;
                locateChange(location);
                //当前为网络定位结果

            } else if (location.getLocType() == BDLocation.TypeServerError) {

                //当前网络定位失败
                //可将定位唯一ID、IMEI、定位失败时间反馈至loc-bugs@baidu.com

            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {

                //当前网络不通

            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {

                //当前缺少定位依据，可能是用户没有授权，建议弹出提示框让用户开启权限
                //可进一步参考onLocDiagnosticMessage中的错误返回码

            }
        }

        /**
         * 回调定位诊断信息，开发者可以根据相关信息解决定位遇到的一些问题
         * 自动回调，相同的diagnosticType只会回调一次
         *
         * @param locType           当前定位类型
         * @param diagnosticType    诊断类型（1~9）
         * @param diagnosticMessage 具体的诊断信息释义
         */
        public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {

            if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_GPS) {

                //建议打开GPS

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_WIFI) {

                //建议打开wifi，不必连接，这样有助于提高网络定位精度！

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CHECK_LOC_PERMISSION) {
                showLocationSettingDialog();
                //定位权限受限，建议提示用户授予APP定位权限！

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CHECK_NET) {

                //网络异常造成定位失败，建议用户确认网络状态是否异常！

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CLOSE_FLYMODE) {

                //手机飞行模式造成定位失败，建议用户关闭飞行模式后再重试定位！

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_INSERT_SIMCARD_OR_OPEN_WIFI) {

                //无法获取任何定位依据，建议用户打开wifi或者插入sim卡重试！

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_OPEN_PHONE_LOC_SWITCH) {

                //无法获取有效定位依据，建议用户打开手机设置里的定位开关后重试！

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_SERVER_FAIL) {

                //百度定位服务端定位失败
                //建议反馈location.getLocationID()和大体定位时间到loc-bugs@baidu.com

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_FAIL_UNKNOWN) {

                //无法获取有效定位依据，但无法确定具体原因
                //建议检查是否有安全软件屏蔽相关定位权限
                //或调用LocationClient.restart()重新启动后重试！

            }
        }

    }

    /**
     * 获取当前的定位地址
     *
     * @return 定位地址
     */
    public BDLocation getCurValidLocation() {
        return curValidLocation;
    }

    /**
     * 获取当前有效的定位信息地址，其中有效包括citycode 有值
     *
     * @return
     */
    public BDLocation getCurValidAndCityLocation() {
        if (curValidLocation != null && !CheckLogicUtil.isEmpty(curValidLocation.getCityCode())) {
            return curValidLocation;
        }
        return null;
    }

    /**
     * 显示设置定位dialog
     */
    protected void showLocationSettingDialog() {

        if (openLocationSettingDialog == null) {
            openLocationSettingDialog = DialogUtil.creatBaseNoTitleDialog(MapLocationActivity.this, "开启位置服务", "去设置", "取消")
                    .getBuilder()
                    .onPositive(new MaterialDialog.SingleButtonCallback() {
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            startActivity(intent);
                        }
                    })
                    .build();
        }

        if (!openLocationSettingDialog.isShowing()) {
            openLocationSettingDialog.show();
        }
    }

    /**
     * 隐藏设置定位dialog
     */
    protected void hidenLocationSettingDialog() {
        if (openLocationSettingDialog.isShowing()) {
            openLocationSettingDialog.hide();
        }
    }

    /**
     * 定位刷新间隔，每次都会调用进行刷新，子类如果要有自己的实现的话，需要重载后不要重写方法，需要super
     *
     * @param location
     */
    protected void locateChange(BDLocation location) {
        if (isOpenUserLocation) {
            updateCurLocationLayer(location);
        }
    }

    protected void updateCurLocationLayer(BDLocation location) {

        updateCurLocationLayer(location, mCurrentDirection);
    }

    protected void updateCurLocationLayer(BDLocation location, float currentDirection) {

        if (location == null) {
            return;
        }

        // 构造定位数据
        MyLocationData locData = new MyLocationData.Builder()
                .latitude(location.getLatitude())
                .direction(currentDirection)
                .longitude(location.getLongitude()).build();
        // 设置定位数据
        mBaiduMap.setMyLocationData(locData);
    }

    /**
     * 开启定位图层
     */
    protected void openCurLocationLayer() {

        // 开启定位图层
        if (!mBaiduMap.isMyLocationEnabled()) {
            mBaiduMap.setMyLocationEnabled(true);
            mBaiduMap.setMyLocationConfiguration(getMyLocationConfig());
        }
    }

    /**
     * 当不需要定位图层时关闭定位图层
     */
    protected void closeCurLocationLayer() {
        mBaiduMap.setMyLocationEnabled(false);
    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        super.onResume();
    }

    @Override
    protected void onStop() {
        //取消注册传感器监听
        super.onStop();
    }
}
